/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javalens.util;

import javalens.util.LinearModelResult;
import javalens.rwrapper.REngineWrapper;
import javalens.*;
import java.util.List;
import javalens.globalconfig.config;
import javalens.maths.Maths;
import javalens.maths.MathsEngineFactory;
import javax.swing.JTextField;

/**
 *
 * @author vermaak
 */
public class Util {

    public static final double NUMERICAL_TOLERANCE = 1.0e-14;

    public static int JTextFieldToInteger(JTextField field) {
        if (field == null || field.getText().equals("")) {
            return 0;
        } else {
            return Integer.valueOf(field.getText());
        }
    }

    public static boolean equals(double d1, double d2, double tolerance) {
        if (Math.abs(d1 - d2) > tolerance) {
            return false;
        }
        return true;
    }

    public static boolean equals(double d1, double d2) {
        return equals(d1, d2, NUMERICAL_TOLERANCE);
    }

    public static double[] createRegularArray(double start, double end, int nSteps) {
        double[] ret = new double[nSteps];
        for (int i = 0; i < nSteps; ++i) {
            ret[i] = start + (end - start) * i / (double) nSteps;
        }
        return ret;
    }

    public static int indexOfMaxElement(double[] array) throws ShouldNeverHappenException {
        int maxI = -1;
        double max = Double.NEGATIVE_INFINITY;
        for (int i = 0; i < array.length; ++i) {
            if (array[i] >= max) {
                maxI = i;
                max = array[i];
            }
        }
        if (maxI == -1) {
            throw new ShouldNeverHappenException("Could not detect index of max element");
        }
        return maxI;
    }

    public static int indexOfMinElement(double[] array) throws ShouldNeverHappenException {
        int minI = -1;
        double min = Double.POSITIVE_INFINITY;
        for (int i = 0; i < array.length; ++i) {
            if (array[i] <= min) {
                minI = i;
                min = array[i];
            }
        }
        if (minI == -1) {
            throw new ShouldNeverHappenException("Could not detect index of min element");
        }
        return minI;
    }

    public static double[] toArray(List<Double> times) {
        double[] ret = new double[times.size()];
        for (int i = 0; i < times.size(); ++i) {
            ret[i] = times.get(i);
        }
        return ret;
    }

    public static double min(double[] x) {
        double min = Double.POSITIVE_INFINITY;
        for (double d : x) {
            if (d < min) {
                min = d;
            }
        }
        return min;
    }

    public static double max(double[] x) {
        double max = Double.NEGATIVE_INFINITY;
        for (double d : x) {
            if (d > max) {
                max = d;
            }
        }
        return max;
    }

    static public double[] fitFivePolynomials(double[] x, double[] y) {
        double[] ret = new double[8];
        Maths w = MathsEngineFactory.getMathsEngine(config.MATHS_ENGINE);
        // fit a line
        LinearModelResult res = w.fitLine(x, y);
        ret[0] = Math.log10(res.getChiSquared());
        ret[1] = res.getCoefficients()[0];
        ret[2] = res.getCoefficients()[1];
        // parabola
        res = w.fitParabola(x, y);
        ret[3] = Math.log10(res.getChiSquared());
        double b = res.getCoefficients()[1];
        double a = res.getCoefficients()[2];
        ret[4] = -b / 2 / a;
        // cubic
        res = w.fitCubic(x, y);
        ret[5] = Math.log10(res.getChiSquared());
        // quartic
        res = w.fitFourthOrderPoly(x, y);
        ret[6] = Math.log10(res.getChiSquared());
        // quintic
        res = w.fitFithOrderPoly(x, y);
        ret[7] = Math.log10(res.getChiSquared());

        return ret;
    }

    public static double JTextFieldToDouble(JTextField field) {
        if (field == null || field.getText().equals("")) {
            return Double.NaN;
        } else {
            return Double.valueOf(field.getText());
        }
    }
}
